Rename GtkSidebar to GtkStackSidebar
authorLars Uebernickel <lars.uebernickel@canonical.com>
Thu, 12 Feb 2015 17:09:13 +0000 (18:09 +0100)
committerLars Uebernickel <lars.uebernickel@canonical.com>
Fri, 13 Feb 2015 17:01:56 +0000 (18:01 +0100)
GtkSidebar is too generic and doesn't fully convey what the widget does.

https://bugzilla.gnome.org/show_bug.cgi?id=744094

20 files changed:
NEWS
demos/gtk-demo/sidebar.c
demos/widget-factory/widget-factory.ui
docs/reference/gtk/gtk-docs.sgml
docs/reference/gtk/gtk3-sections.txt
docs/reference/gtk/gtk3.types.in
docs/reference/gtk/visual_index.xml
docs/tools/widgets.c
gtk/Makefile.am
gtk/gtk-autocleanups.h
gtk/gtk.h
gtk/gtksidebar.c [deleted file]
gtk/gtksidebar.h [deleted file]
gtk/gtkstacksidebar.c [new file with mode: 0644]
gtk/gtkstacksidebar.h [new file with mode: 0644]
gtk/inspector/window.ui
gtk/makefile.msc.in
po-properties/POTFILES.in
po/POTFILES.in
tests/teststack.c

diff --git a/NEWS b/NEWS
index ed5348228b092d45d6ce024925cd24e5acdab12f..61643b32f4056c4d65c3f95c862351c08d54cec2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,8 @@ Overview of Changes in GTK+ 3.15.5
 * GtkScrolledWindow has gained a new ::edge-reached signal, which
   triggers when the edge of the scrollable area is reached.
 
+* GtkSidebar was renamed to GtkStackSidebar to better convey what it does
+
 * CSS:
  - Performance improvements
 
index f135794126094f22e611895df0cbb8b8ef3c6908..1422d109515839f9935cbedfb795685593b40ada 100644 (file)
@@ -1,9 +1,9 @@
-/* Sidebar
+/* Stack Sidebar
  *
- * GtkSidebar provides an automatic sidebar widget to control navigation
- * of a GtkStack object. This widget automatically updates it content
- * based on what is presently available in the GtkStack object, and
- * using the "title" child property to set the display labels.
+ * GtkStackSidebar provides an automatic sidebar widget to control
+ * navigation of a GtkStack object. This widget automatically updates it
+ * content based on what is presently available in the GtkStack object,
+ * and using the "title" child property to set the display labels.
  */
 
 #include <glib/gi18n.h>
@@ -21,7 +21,7 @@ do_sidebar (GtkWidget *do_widget)
   GtkWidget *header;
   const gchar* pages[] = {
     "Welcome to GTK+",
-    "GtkSidebar Widget",
+    "GtkStackSidebar Widget",
     "Automatic navigation",
     "Consistent appearance",
     "Scrolling",
@@ -43,18 +43,18 @@ do_sidebar (GtkWidget *do_widget)
       header = gtk_header_bar_new ();
       gtk_header_bar_set_show_close_button (GTK_HEADER_BAR(header), TRUE);
       gtk_window_set_titlebar (GTK_WINDOW(window), header);
-      gtk_window_set_title (GTK_WINDOW(window), "Sidebar demo");
+      gtk_window_set_title (GTK_WINDOW(window), "Stack Sidebar demo");
 
       g_signal_connect (window, "destroy",
                         G_CALLBACK (gtk_widget_destroyed), &window);
 
       box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-      sidebar = gtk_sidebar_new ();
+      sidebar = gtk_stack_sidebar_new ();
       gtk_box_pack_start (GTK_BOX (box), sidebar, FALSE, FALSE, 0);
 
       stack = gtk_stack_new ();
       gtk_stack_set_transition_type (GTK_STACK (stack), GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN);
-      gtk_sidebar_set_stack (GTK_SIDEBAR (sidebar), GTK_STACK (stack));
+      gtk_stack_sidebar_set_stack (GTK_STACK_SIDEBAR (sidebar), GTK_STACK (stack));
 
       /* Separator between sidebar and stack */
       widget = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
index aac64b9b0d8e168b10fc3d34396927bd365265ad..c6ef6e6f3f4a837c834ca1f70757797284ec389e 100644 (file)
@@ -3400,7 +3400,7 @@ microphone-sensitivity-medium-symbolic</property>
                             <property name="visible">True</property>
                             <property name="orientation">horizontal</property>
                             <child>
-                              <object class="GtkSidebar">
+                              <object class="GtkStackSidebar">
                                 <property name="visible">True</property>
                                 <property name="stack">sidebar_stack</property>
                               </object>
index e6712a35c2dd17b81554e333ee5e151ca650a885..9e69992a6351438ac8bda96be5dbd14bb41eba3a 100644 (file)
@@ -76,7 +76,7 @@
       <xi:include href="xml/gtkflowbox.xml" />
       <xi:include href="xml/gtkstack.xml" />
       <xi:include href="xml/gtkstackswitcher.xml" />
-      <xi:include href="xml/gtksidebar.xml" />
+      <xi:include href="xml/gtkstacksidebar.xml" />
       <xi:include href="xml/gtkactionbar.xml" />
       <xi:include href="xml/gtkheaderbar.xml" />
       <xi:include href="xml/gtkoverlay.xml" />
index 7db2ee399d0e4a462267ff70599e3adf43448dc8..1d76872e99eb057a8d9d4b6f87b91d5f620d010d 100644 (file)
@@ -8214,24 +8214,24 @@ gtk_gesture_zoom_get_type
 </SECTION>
 
 <SECTION>
-<FILE>gtksidebar</FILE>
-GtkSidebar
-GtkSidebarClass
-gtk_sidebar_new
-gtk_sidebar_set_stack
-gtk_sidebar_get_stack
+<FILE>gtkstacksidebar</FILE>
+GtkStackSidebar
+GtkStackSidebarClass
+gtk_stack_sidebar_new
+gtk_stack_sidebar_set_stack
+gtk_stack_sidebar_get_stack
 
 <SUBSECTION Standard>
 GTK_TYPE_SIDEBAR
-GTK_SIDEBAR
-GTK_SIDEBAR_CLASS
+GTK_STACK_SIDEBAR
+GTK_STACK_SIDEBAR_CLASS
 GTK_IS_SIDEBAR
 GTK_IS_SIDEBAR_CLASS
-GTK_SIDEBAR_GET_CLASS
+GTK_STACK_SIDEBAR_GET_CLASS
 
 <SUBSECTION Private>
-GtkSidebarPrivate
-gtk_sidebar_get_type
+GtkStackSidebarPrivate
+gtk_stack_sidebar_get_type
 </SECTION>
 
 <SECTION>
index 0bc2c6a055a92ca5e265c9b51808cb32a1bf2869..4b206223e8887812421d19eb9626c748ae0bdb4f 100644 (file)
@@ -173,7 +173,7 @@ gtk_separator_get_type
 gtk_separator_menu_item_get_type
 gtk_separator_tool_item_get_type
 gtk_settings_get_type
-gtk_sidebar_get_type
+gtk_stack_sidebar_get_type
 gtk_size_group_get_type
 @ENABLE_ON_X11@gtk_socket_get_type
 gtk_spin_button_get_type
index 6e58e5397c9e24d284d37bca50841d6bb18f53f5..c3f37767582d4490585e42555896cd46750c7eb4 100644 (file)
     <link linkend="GtkStackSwitcher">
       <inlinegraphic fileref="stackswitcher.png" format="PNG"></inlinegraphic>
     </link>
-    <link linkend="GtkSidebar">
+    <link linkend="GtkStackSidebar">
       <inlinegraphic fileref="sidebar.png" format="PNG"></inlinegraphic>
     </link>
     <link linkend="GtkTreeView">
index c6d1afb1e1d0e6e9f9bd5e7bbcc4bf315b7d2555..932daf174610359d557698c78fbffe4ae0734e6e 100644 (file)
@@ -1407,8 +1407,8 @@ create_sidebar (void)
   gtk_widget_show (view);
   gtk_stack_add_titled (GTK_STACK (stack), view, "page2", "Page 2");
 
-  sidebar = gtk_sidebar_new ();
-  gtk_sidebar_set_stack (GTK_SIDEBAR (sidebar), GTK_STACK (stack));
+  sidebar = gtk_stack_sidebar_new ();
+  gtk_stack_sidebar_set_stack (GTK_STACK_SIDEBAR (sidebar), GTK_STACK (stack));
 
   frame = gtk_frame_new (NULL);
   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
index ed874754d34198873027bb594f4812dc33e49905..721a76d5a25b064b2634965679373f53c30a3846 100644 (file)
@@ -269,7 +269,7 @@ gtk_public_h_sources =              \
        gtkseparatortoolitem.h  \
        gtksettings.h           \
        gtkshow.h               \
-       gtksidebar.h            \
+       gtkstacksidebar.h       \
        gtksizegroup.h          \
        gtksizerequest.h        \
        gtksocket.h             \
@@ -787,7 +787,7 @@ gtk_base_c_sources =                \
        gtksizerequest.c        \
        gtksizerequestcache.c   \
        gtkshow.c               \
-       gtksidebar.c            \
+       gtkstacksidebar.c       \
        gtkspinbutton.c         \
        gtkspinner.c            \
        gtkstack.c              \
index c846f892d51605e78e3e9d06fc4c45096aec8352..536187248b1cfe03466ea81399aaaff3b212e0de 100644 (file)
@@ -165,7 +165,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSeparator, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSeparatorMenuItem, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSeparatorToolItem, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSettings, g_object_unref)
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSidebar, g_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkStackSidebar, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSizeGroup, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSpinButton, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSpinner, g_object_unref)
index 1d174c7a23e4fd0ba3a7293a3fea2ef9695760c8..3cbd13fcd55803a5952201c962773dc56775348b 100644 (file)
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
 #include <gtk/gtkseparatortoolitem.h>
 #include <gtk/gtksettings.h>
 #include <gtk/gtkshow.h>
-#include <gtk/gtksidebar.h>
+#include <gtk/gtkstacksidebar.h>
 #include <gtk/gtksizegroup.h>
 #include <gtk/gtksizerequest.h>
 #include <gtk/gtkspinbutton.h>
diff --git a/gtk/gtksidebar.c b/gtk/gtksidebar.c
deleted file mode 100644 (file)
index 39c3321..0000000
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * Copyright (c) 2014 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Author:
- *      Ikey Doherty <michael.i.doherty@intel.com>
- */
-
-#include "config.h"
-
-#include "gtksidebar.h"
-
-#include "gtklabel.h"
-#include "gtklistbox.h"
-#include "gtkscrolledwindow.h"
-#include "gtkseparator.h"
-#include "gtkstylecontext.h"
-#include "gtkprivate.h"
-#include "gtkintl.h"
-
-/**
- * SECTION:gtksidebar
- * @Title: GtkSidebar
- * @Short_description: An automatic sidebar widget
- *
- * A GtkSidebar enables you to quickly and easily provide a consistent
- * "sidebar" object for your user interface.
- *
- * In order to use a GtkSidebar, you simply use a GtkStack to organize
- * your UI flow, and add the sidebar to your sidebar area. You can use
- * gtk_sidebar_set_stack() to connect the #GtkSidebar to the #GtkStack.
- *
- * Since: 3.16
- */
-struct _GtkSidebarPrivate
-{
-  GtkListBox *list;
-  GtkStack *stack;
-  GHashTable *rows;
-  gboolean in_child_changed;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE (GtkSidebar, gtk_sidebar, GTK_TYPE_BIN)
-
-enum
-{
-  PROP_0,
-  PROP_STACK,
-  N_PROPERTIES
-};
-static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
-
-static void
-gtk_sidebar_set_property (GObject    *object,
-                          guint       prop_id,
-                          const       GValue *value,
-                          GParamSpec *pspec)
-{
-  switch (prop_id)
-    {
-    case PROP_STACK:
-      gtk_sidebar_set_stack (GTK_SIDEBAR (object), g_value_get_object (value));
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-    }
-}
-
-static void
-gtk_sidebar_get_property (GObject    *object,
-                          guint       prop_id,
-                          GValue     *value,
-                          GParamSpec *pspec)
-{
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (GTK_SIDEBAR (object));
-
-  switch (prop_id)
-    {
-    case PROP_STACK:
-      g_value_set_object (value, priv->stack);
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-    }
-}
-
-static void
-update_header (GtkListBoxRow *row,
-               GtkListBoxRow *before,
-               gpointer       userdata)
-{
-  GtkWidget *ret = NULL;
-
-  if (before && !gtk_list_box_row_get_header (row))
-    {
-      ret = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
-      gtk_list_box_row_set_header (row, ret);
-    }
-}
-
-static gint
-sort_list (GtkListBoxRow *row1,
-           GtkListBoxRow *row2,
-           gpointer       userdata)
-{
-  GtkSidebar *sidebar = GTK_SIDEBAR (userdata);
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (sidebar);
-  GtkWidget *item;
-  GtkWidget *widget;
-  gint left = 0; gint right = 0;
-
-
-  if (row1)
-    {
-      item = gtk_bin_get_child (GTK_BIN (row1));
-      widget = g_object_get_data (G_OBJECT (item), "stack-child");
-      gtk_container_child_get (GTK_CONTAINER (priv->stack), widget,
-                               "position", &left,
-                               NULL);
-    }
-
-  if (row2)
-    {
-      item = gtk_bin_get_child (GTK_BIN (row2));
-      widget = g_object_get_data (G_OBJECT (item), "stack-child");
-      gtk_container_child_get (GTK_CONTAINER (priv->stack), widget,
-                               "position", &right,
-                               NULL);
-    }
-
-  if (left < right)
-    return  -1;
-
-  if (left == right)
-    return 0;
-
-  return 1;
-}
-
-static void
-gtk_sidebar_row_selected (GtkListBox    *box,
-                          GtkListBoxRow *row,
-                          gpointer       userdata)
-{
-  GtkSidebar *sidebar = GTK_SIDEBAR (userdata);
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (sidebar);
-  GtkWidget *item;
-  GtkWidget *widget;
-
-  if (priv->in_child_changed)
-    return;
-
-  if (!row)
-    return;
-
-  item = gtk_bin_get_child (GTK_BIN (row));
-  widget = g_object_get_data (G_OBJECT (item), "stack-child");
-  gtk_stack_set_visible_child (priv->stack, widget);
-}
-
-static void
-gtk_sidebar_init (GtkSidebar *sidebar)
-{
-  GtkStyleContext *style;
-  GtkSidebarPrivate *priv;
-  GtkWidget *sw;
-
-  priv = gtk_sidebar_get_instance_private (sidebar);
-
-  sw = gtk_scrolled_window_new (NULL, NULL);
-  gtk_widget_show (sw);
-  gtk_widget_set_no_show_all (sw, TRUE);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
-                                  GTK_POLICY_NEVER,
-                                  GTK_POLICY_AUTOMATIC);
-
-  gtk_container_add (GTK_CONTAINER (sidebar), sw);
-
-  priv->list = GTK_LIST_BOX (gtk_list_box_new ());
-  gtk_widget_show (GTK_WIDGET (priv->list));
-
-  gtk_container_add (GTK_CONTAINER (sw), GTK_WIDGET (priv->list));
-
-  gtk_list_box_set_header_func (priv->list, update_header, sidebar, NULL);
-  gtk_list_box_set_sort_func (priv->list, sort_list, sidebar, NULL);
-
-  g_signal_connect (priv->list, "row-selected",
-                    G_CALLBACK (gtk_sidebar_row_selected), sidebar);
-
-  style = gtk_widget_get_style_context (GTK_WIDGET (sidebar));
-  gtk_style_context_add_class (style, "sidebar");
-
-  priv->rows = g_hash_table_new (NULL, NULL);
-}
-
-static void
-update_row (GtkSidebar *sidebar,
-            GtkWidget  *widget,
-            GtkWidget  *row)
-{
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (sidebar);
-  GtkWidget *item;
-  gchar *title;
-  gboolean needs_attention;
-  GtkStyleContext *context;
-
-  gtk_container_child_get (GTK_CONTAINER (priv->stack), widget,
-                           "title", &title,
-                           "needs-attention", &needs_attention,
-                           NULL);
-
-  item = gtk_bin_get_child (GTK_BIN (row));
-  gtk_label_set_text (GTK_LABEL (item), title);
-
-  gtk_widget_set_visible (row, gtk_widget_get_visible (widget) && title != NULL);
-
-  context = gtk_widget_get_style_context (row);
-  if (needs_attention)
-     gtk_style_context_add_class (context, GTK_STYLE_CLASS_NEEDS_ATTENTION);
-  else
-    gtk_style_context_remove_class (context, GTK_STYLE_CLASS_NEEDS_ATTENTION);
-
-  g_free (title);
-}
-
-static void
-on_position_updated (GtkWidget  *widget,
-                     GParamSpec *pspec,
-                     GtkSidebar *sidebar)
-{
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (sidebar);
-
-  gtk_list_box_invalidate_sort (priv->list);
-}
-
-static void
-on_child_updated (GtkWidget  *widget,
-                  GParamSpec *pspec,
-                  GtkSidebar *sidebar)
-{
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (sidebar);
-  GtkWidget *row;
-
-  row = g_hash_table_lookup (priv->rows, widget);
-  update_row (sidebar, widget, row);
-}
-
-static void
-add_child (GtkWidget  *widget,
-           GtkSidebar *sidebar)
-{
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (sidebar);
-  GtkStyleContext *style;
-  GtkWidget *item;
-  GtkWidget *row;
-
-  /* Check we don't actually already know about this widget */
-  if (g_hash_table_lookup (priv->rows, widget))
-    return;
-
-  /* Make a pretty item when we add kids */
-  item = gtk_label_new ("");
-  gtk_widget_set_halign (item, GTK_ALIGN_START);
-  gtk_widget_set_valign (item, GTK_ALIGN_CENTER);
-  row = gtk_list_box_row_new ();
-  gtk_container_add (GTK_CONTAINER (row), item);
-  gtk_widget_show (item);
-
-  update_row (sidebar, widget, row);
-
-  /* Fix up styling */
-  style = gtk_widget_get_style_context (row);
-  gtk_style_context_add_class (style, "sidebar-item");
-
-  /* Hook up for events */
-  g_signal_connect (widget, "child-notify::title",
-                    G_CALLBACK (on_child_updated), sidebar);
-  g_signal_connect (widget, "child-notify::needs-attention",
-                    G_CALLBACK (on_child_updated), sidebar);
-  g_signal_connect (widget, "notify::visible",
-                    G_CALLBACK (on_child_updated), sidebar);
-  g_signal_connect (widget, "child-notify::position",
-                    G_CALLBACK (on_position_updated), sidebar);
-
-  g_object_set_data (G_OBJECT (item), "stack-child", widget);
-  g_hash_table_insert (priv->rows, widget, row);
-  gtk_container_add (GTK_CONTAINER (priv->list), row);
-}
-
-static void
-remove_child (GtkWidget  *widget,
-              GtkSidebar *sidebar)
-{
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (sidebar);
-  GtkWidget *row;
-
-  row = g_hash_table_lookup (priv->rows, widget);
-  if (!row)
-    return;
-
-  g_signal_handlers_disconnect_by_func (widget, on_child_updated, sidebar);
-  g_signal_handlers_disconnect_by_func (widget, on_position_updated, sidebar);
-
-  gtk_container_remove (GTK_CONTAINER (priv->list), row);
-  g_hash_table_remove (priv->rows, widget);
-}
-
-static void
-populate_sidebar (GtkSidebar *sidebar)
-{
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (sidebar);
-  GtkWidget *widget, *row;
-
-  gtk_container_foreach (GTK_CONTAINER (priv->stack), (GtkCallback)add_child, sidebar);
-
-  widget = gtk_stack_get_visible_child (priv->stack);
-  if (widget)
-    {
-      row = g_hash_table_lookup (priv->rows, widget);
-      gtk_list_box_select_row (priv->list, GTK_LIST_BOX_ROW (row));
-    }
-}
-
-static void
-clear_sidebar (GtkSidebar *sidebar)
-{
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (sidebar);
-
-  gtk_container_foreach (GTK_CONTAINER (priv->stack), (GtkCallback)remove_child, sidebar);
-}
-
-static void
-on_child_changed (GtkWidget  *widget,
-                  GParamSpec *pspec,
-                  GtkSidebar *sidebar)
-{
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (sidebar);
-  GtkWidget *child;
-  GtkWidget *row;
-
-  child = gtk_stack_get_visible_child (GTK_STACK (widget));
-  row = g_hash_table_lookup (priv->rows, child);
-  if (row != NULL)
-    {
-      priv->in_child_changed = TRUE;
-      gtk_list_box_select_row (priv->list, GTK_LIST_BOX_ROW (row));
-      priv->in_child_changed = FALSE;
-    }
-}
-
-static void
-on_stack_child_added (GtkContainer *container,
-                      GtkWidget    *widget,
-                      GtkSidebar   *sidebar)
-{
-  add_child (widget, sidebar);
-}
-
-static void
-on_stack_child_removed (GtkContainer *container,
-                        GtkWidget    *widget,
-                        GtkSidebar   *sidebar)
-{
-  remove_child (widget, sidebar);
-}
-
-static void
-disconnect_stack_signals (GtkSidebar *sidebar)
-{
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (sidebar);
-
-  g_signal_handlers_disconnect_by_func (priv->stack, on_stack_child_added, sidebar);
-  g_signal_handlers_disconnect_by_func (priv->stack, on_stack_child_removed, sidebar);
-  g_signal_handlers_disconnect_by_func (priv->stack, on_child_changed, sidebar);
-  g_signal_handlers_disconnect_by_func (priv->stack, disconnect_stack_signals, sidebar);
-}
-
-static void
-connect_stack_signals (GtkSidebar *sidebar)
-{
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (sidebar);
-
-  g_signal_connect_after (priv->stack, "add",
-                          G_CALLBACK (on_stack_child_added), sidebar);
-  g_signal_connect_after (priv->stack, "remove",
-                          G_CALLBACK (on_stack_child_removed), sidebar);
-  g_signal_connect (priv->stack, "notify::visible-child",
-                    G_CALLBACK (on_child_changed), sidebar);
-  g_signal_connect_swapped (priv->stack, "destroy",
-                            G_CALLBACK (disconnect_stack_signals), sidebar);
-}
-
-static void
-gtk_sidebar_dispose (GObject *object)
-{
-  GtkSidebar *sidebar = GTK_SIDEBAR (object);
-
-  gtk_sidebar_set_stack (sidebar, NULL);
-
-  G_OBJECT_CLASS (gtk_sidebar_parent_class)->dispose (object);
-}
-
-static void
-gtk_sidebar_finalize (GObject *object)
-{
-  GtkSidebar *sidebar = GTK_SIDEBAR (object);
-  GtkSidebarPrivate *priv = gtk_sidebar_get_instance_private (sidebar);
-
-  g_hash_table_destroy (priv->rows);
-
-  G_OBJECT_CLASS (gtk_sidebar_parent_class)->finalize (object);
-}
-
-static void
-gtk_sidebar_class_init (GtkSidebarClass *klass)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-  object_class->dispose = gtk_sidebar_dispose;
-  object_class->finalize = gtk_sidebar_finalize;
-  object_class->set_property = gtk_sidebar_set_property;
-  object_class->get_property = gtk_sidebar_get_property;
-
-  obj_properties[PROP_STACK] =
-      g_param_spec_object (I_("stack"), P_("Stack"),
-                           P_("Associated stack for this GtkSidebar"),
-                           GTK_TYPE_STACK,
-                           G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY);
-
-  g_object_class_install_properties (object_class, N_PROPERTIES, obj_properties);
-}
-
-/**
- * gtk_sidebar_new:
- *
- * Creates a new sidebar.
- *
- * Returns: the new #GtkSidebar
- *
- * Since: 3.16
- */
-GtkWidget *
-gtk_sidebar_new (void)
-{
-  return GTK_WIDGET (g_object_new (GTK_TYPE_SIDEBAR, NULL));
-}
-
-/**
- * gtk_sidebar_set_stack:
- * @sidebar: a #GtkSidebar
- * @stack: a #GtkStack
- *
- * Set the #GtkStack associated with this #GtkSidebar.
- *
- * The sidebar widget will automatically update according to the order
- * (packing) and items within the given #GtkStack.
- *
- * Since: 3.16
- */
-void
-gtk_sidebar_set_stack (GtkSidebar *sidebar,
-                       GtkStack   *stack)
-{
-  GtkSidebarPrivate *priv;
-
-  g_return_if_fail (GTK_IS_SIDEBAR (sidebar));
-  g_return_if_fail (GTK_IS_STACK (stack) || stack == NULL);
-
-  priv = gtk_sidebar_get_instance_private (sidebar);
-
-  if (priv->stack == stack)
-    return;
-
-  if (priv->stack)
-    {
-      disconnect_stack_signals (sidebar);
-      clear_sidebar (sidebar);
-      g_clear_object (&priv->stack);
-    }
-  if (stack)
-    {
-      priv->stack = g_object_ref (stack);
-      populate_sidebar (sidebar);
-      connect_stack_signals (sidebar);
-    }
-
-  gtk_widget_queue_resize (GTK_WIDGET (sidebar));
-
-  g_object_notify (G_OBJECT (sidebar), "stack");
-}
-
-/**
- * gtk_sidebar_get_stack:
- * @sidebar: a #GtkSidebar
- *
- * Retrieves the stack.
- * See gtk_sidebar_set_stack().
- *
- * Returns: (transfer full): the associated #GtkStack or
- *     %NULL if none has been set explicitly
- *
- * Since: 3.16
- */
-GtkStack *
-gtk_sidebar_get_stack (GtkSidebar *sidebar)
-{
-  GtkSidebarPrivate *priv;
-
-  g_return_val_if_fail (GTK_IS_SIDEBAR (sidebar), NULL);
-
-  priv = gtk_sidebar_get_instance_private (sidebar);
-
-  return GTK_STACK (priv->stack);
-}
diff --git a/gtk/gtksidebar.h b/gtk/gtksidebar.h
deleted file mode 100644 (file)
index a2c4d8c..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2014 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Author:
- *      Ikey Doherty <michael.i.doherty@intel.com>
- */
-
-#ifndef __GTK_SIDEBAR_H__
-#define __GTK_SIDEBAR_H__
-
-#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
-#error "Only <gtk/gtk.h> can be included directly."
-#endif
-
-#include <gtk/gtkbin.h>
-#include <gtk/gtkstack.h>
-
-G_BEGIN_DECLS
-
-#define GTK_TYPE_SIDEBAR                 (gtk_sidebar_get_type ())
-#define GTK_SIDEBAR(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SIDEBAR, GtkSidebar))
-#define GTK_IS_SIDEBAR(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SIDEBAR))
-#define GTK_SIDEBAR_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SIDEBAR, GtkSidebarClass))
-#define GTK_IS_SIDEBAR_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SIDEBAR))
-#define GTK_SIDEBAR_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SIDEBAR, GtkSidebarClass))
-
-typedef struct _GtkSidebar        GtkSidebar;
-typedef struct _GtkSidebarPrivate GtkSidebarPrivate;
-typedef struct _GtkSidebarClass   GtkSidebarClass;
-
-struct _GtkSidebar
-{
-  GtkBin parent;
-};
-
-struct _GtkSidebarClass
-{
-  GtkBinClass parent_class;
-
-  /* Padding for future expansion */
-  void (*_gtk_reserved1) (void);
-  void (*_gtk_reserved2) (void);
-  void (*_gtk_reserved3) (void);
-  void (*_gtk_reserved4) (void);
-};
-
-GDK_AVAILABLE_IN_3_16
-GType       gtk_sidebar_get_type  (void) G_GNUC_CONST;
-GDK_AVAILABLE_IN_3_16
-GtkWidget * gtk_sidebar_new       (void);
-GDK_AVAILABLE_IN_3_16
-void        gtk_sidebar_set_stack (GtkSidebar *sidebar,
-                                   GtkStack   *stack);
-GDK_AVAILABLE_IN_3_16
-GtkStack *  gtk_sidebar_get_stack (GtkSidebar *sidebar);
-
-G_END_DECLS
-
-#endif /* __GTK_SIDEBAR_H__ */
diff --git a/gtk/gtkstacksidebar.c b/gtk/gtkstacksidebar.c
new file mode 100644 (file)
index 0000000..cedc104
--- /dev/null
@@ -0,0 +1,533 @@
+/*
+ * Copyright (c) 2014 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author:
+ *      Ikey Doherty <michael.i.doherty@intel.com>
+ */
+
+#include "config.h"
+
+#include "gtkstacksidebar.h"
+
+#include "gtklabel.h"
+#include "gtklistbox.h"
+#include "gtkscrolledwindow.h"
+#include "gtkseparator.h"
+#include "gtkstylecontext.h"
+#include "gtkprivate.h"
+#include "gtkintl.h"
+
+/**
+ * SECTION:gtkstacksidebar
+ * @Title: GtkStackSidebar
+ * @Short_description: An automatic sidebar widget
+ *
+ * A GtkStackSidebar enables you to quickly and easily provide a
+ * consistent "sidebar" object for your user interface.
+ *
+ * In order to use a GtkStackSidebar, you simply use a GtkStack to
+ * organize your UI flow, and add the sidebar to your sidebar area. You
+ * can use gtk_stack_sidebar_set_stack() to connect the #GtkStackSidebar
+ * to the #GtkStack.
+ *
+ * Since: 3.16
+ */
+struct _GtkStackSidebarPrivate
+{
+  GtkListBox *list;
+  GtkStack *stack;
+  GHashTable *rows;
+  gboolean in_child_changed;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkStackSidebar, gtk_stack_sidebar, GTK_TYPE_BIN)
+
+enum
+{
+  PROP_0,
+  PROP_STACK,
+  N_PROPERTIES
+};
+static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
+
+static void
+gtk_stack_sidebar_set_property (GObject    *object,
+                                guint       prop_id,
+                                const       GValue *value,
+                                GParamSpec *pspec)
+{
+  switch (prop_id)
+    {
+    case PROP_STACK:
+      gtk_stack_sidebar_set_stack (GTK_STACK_SIDEBAR (object), g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_stack_sidebar_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (GTK_STACK_SIDEBAR (object));
+
+  switch (prop_id)
+    {
+    case PROP_STACK:
+      g_value_set_object (value, priv->stack);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+update_header (GtkListBoxRow *row,
+               GtkListBoxRow *before,
+               gpointer       userdata)
+{
+  GtkWidget *ret = NULL;
+
+  if (before && !gtk_list_box_row_get_header (row))
+    {
+      ret = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+      gtk_list_box_row_set_header (row, ret);
+    }
+}
+
+static gint
+sort_list (GtkListBoxRow *row1,
+           GtkListBoxRow *row2,
+           gpointer       userdata)
+{
+  GtkStackSidebar *sidebar = GTK_STACK_SIDEBAR (userdata);
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
+  GtkWidget *item;
+  GtkWidget *widget;
+  gint left = 0; gint right = 0;
+
+
+  if (row1)
+    {
+      item = gtk_bin_get_child (GTK_BIN (row1));
+      widget = g_object_get_data (G_OBJECT (item), "stack-child");
+      gtk_container_child_get (GTK_CONTAINER (priv->stack), widget,
+                               "position", &left,
+                               NULL);
+    }
+
+  if (row2)
+    {
+      item = gtk_bin_get_child (GTK_BIN (row2));
+      widget = g_object_get_data (G_OBJECT (item), "stack-child");
+      gtk_container_child_get (GTK_CONTAINER (priv->stack), widget,
+                               "position", &right,
+                               NULL);
+    }
+
+  if (left < right)
+    return  -1;
+
+  if (left == right)
+    return 0;
+
+  return 1;
+}
+
+static void
+gtk_stack_sidebar_row_selected (GtkListBox    *box,
+                                GtkListBoxRow *row,
+                                gpointer       userdata)
+{
+  GtkStackSidebar *sidebar = GTK_STACK_SIDEBAR (userdata);
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
+  GtkWidget *item;
+  GtkWidget *widget;
+
+  if (priv->in_child_changed)
+    return;
+
+  if (!row)
+    return;
+
+  item = gtk_bin_get_child (GTK_BIN (row));
+  widget = g_object_get_data (G_OBJECT (item), "stack-child");
+  gtk_stack_set_visible_child (priv->stack, widget);
+}
+
+static void
+gtk_stack_sidebar_init (GtkStackSidebar *sidebar)
+{
+  GtkStyleContext *style;
+  GtkStackSidebarPrivate *priv;
+  GtkWidget *sw;
+
+  priv = gtk_stack_sidebar_get_instance_private (sidebar);
+
+  sw = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_show (sw);
+  gtk_widget_set_no_show_all (sw, TRUE);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+                                  GTK_POLICY_NEVER,
+                                  GTK_POLICY_AUTOMATIC);
+
+  gtk_container_add (GTK_CONTAINER (sidebar), sw);
+
+  priv->list = GTK_LIST_BOX (gtk_list_box_new ());
+  gtk_widget_show (GTK_WIDGET (priv->list));
+
+  gtk_container_add (GTK_CONTAINER (sw), GTK_WIDGET (priv->list));
+
+  gtk_list_box_set_header_func (priv->list, update_header, sidebar, NULL);
+  gtk_list_box_set_sort_func (priv->list, sort_list, sidebar, NULL);
+
+  g_signal_connect (priv->list, "row-selected",
+                    G_CALLBACK (gtk_stack_sidebar_row_selected), sidebar);
+
+  style = gtk_widget_get_style_context (GTK_WIDGET (sidebar));
+  gtk_style_context_add_class (style, "sidebar");
+
+  priv->rows = g_hash_table_new (NULL, NULL);
+}
+
+static void
+update_row (GtkStackSidebar *sidebar,
+            GtkWidget       *widget,
+            GtkWidget       *row)
+{
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
+  GtkWidget *item;
+  gchar *title;
+  gboolean needs_attention;
+  GtkStyleContext *context;
+
+  gtk_container_child_get (GTK_CONTAINER (priv->stack), widget,
+                           "title", &title,
+                           "needs-attention", &needs_attention,
+                           NULL);
+
+  item = gtk_bin_get_child (GTK_BIN (row));
+  gtk_label_set_text (GTK_LABEL (item), title);
+
+  gtk_widget_set_visible (row, gtk_widget_get_visible (widget) && title != NULL);
+
+  context = gtk_widget_get_style_context (row);
+  if (needs_attention)
+     gtk_style_context_add_class (context, GTK_STYLE_CLASS_NEEDS_ATTENTION);
+  else
+    gtk_style_context_remove_class (context, GTK_STYLE_CLASS_NEEDS_ATTENTION);
+
+  g_free (title);
+}
+
+static void
+on_position_updated (GtkWidget       *widget,
+                     GParamSpec      *pspec,
+                     GtkStackSidebar *sidebar)
+{
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
+
+  gtk_list_box_invalidate_sort (priv->list);
+}
+
+static void
+on_child_updated (GtkWidget       *widget,
+                  GParamSpec      *pspec,
+                  GtkStackSidebar *sidebar)
+{
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
+  GtkWidget *row;
+
+  row = g_hash_table_lookup (priv->rows, widget);
+  update_row (sidebar, widget, row);
+}
+
+static void
+add_child (GtkWidget       *widget,
+           GtkStackSidebar *sidebar)
+{
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
+  GtkStyleContext *style;
+  GtkWidget *item;
+  GtkWidget *row;
+
+  /* Check we don't actually already know about this widget */
+  if (g_hash_table_lookup (priv->rows, widget))
+    return;
+
+  /* Make a pretty item when we add kids */
+  item = gtk_label_new ("");
+  gtk_widget_set_halign (item, GTK_ALIGN_START);
+  gtk_widget_set_valign (item, GTK_ALIGN_CENTER);
+  row = gtk_list_box_row_new ();
+  gtk_container_add (GTK_CONTAINER (row), item);
+  gtk_widget_show (item);
+
+  update_row (sidebar, widget, row);
+
+  /* Fix up styling */
+  style = gtk_widget_get_style_context (row);
+  gtk_style_context_add_class (style, "sidebar-item");
+
+  /* Hook up for events */
+  g_signal_connect (widget, "child-notify::title",
+                    G_CALLBACK (on_child_updated), sidebar);
+  g_signal_connect (widget, "child-notify::needs-attention",
+                    G_CALLBACK (on_child_updated), sidebar);
+  g_signal_connect (widget, "notify::visible",
+                    G_CALLBACK (on_child_updated), sidebar);
+  g_signal_connect (widget, "child-notify::position",
+                    G_CALLBACK (on_position_updated), sidebar);
+
+  g_object_set_data (G_OBJECT (item), "stack-child", widget);
+  g_hash_table_insert (priv->rows, widget, row);
+  gtk_container_add (GTK_CONTAINER (priv->list), row);
+}
+
+static void
+remove_child (GtkWidget       *widget,
+              GtkStackSidebar *sidebar)
+{
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
+  GtkWidget *row;
+
+  row = g_hash_table_lookup (priv->rows, widget);
+  if (!row)
+    return;
+
+  g_signal_handlers_disconnect_by_func (widget, on_child_updated, sidebar);
+  g_signal_handlers_disconnect_by_func (widget, on_position_updated, sidebar);
+
+  gtk_container_remove (GTK_CONTAINER (priv->list), row);
+  g_hash_table_remove (priv->rows, widget);
+}
+
+static void
+populate_sidebar (GtkStackSidebar *sidebar)
+{
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
+  GtkWidget *widget, *row;
+
+  gtk_container_foreach (GTK_CONTAINER (priv->stack), (GtkCallback)add_child, sidebar);
+
+  widget = gtk_stack_get_visible_child (priv->stack);
+  if (widget)
+    {
+      row = g_hash_table_lookup (priv->rows, widget);
+      gtk_list_box_select_row (priv->list, GTK_LIST_BOX_ROW (row));
+    }
+}
+
+static void
+clear_sidebar (GtkStackSidebar *sidebar)
+{
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
+
+  gtk_container_foreach (GTK_CONTAINER (priv->stack), (GtkCallback)remove_child, sidebar);
+}
+
+static void
+on_child_changed (GtkWidget       *widget,
+                  GParamSpec      *pspec,
+                  GtkStackSidebar *sidebar)
+{
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
+  GtkWidget *child;
+  GtkWidget *row;
+
+  child = gtk_stack_get_visible_child (GTK_STACK (widget));
+  row = g_hash_table_lookup (priv->rows, child);
+  if (row != NULL)
+    {
+      priv->in_child_changed = TRUE;
+      gtk_list_box_select_row (priv->list, GTK_LIST_BOX_ROW (row));
+      priv->in_child_changed = FALSE;
+    }
+}
+
+static void
+on_stack_child_added (GtkContainer    *container,
+                      GtkWidget       *widget,
+                      GtkStackSidebar *sidebar)
+{
+  add_child (widget, sidebar);
+}
+
+static void
+on_stack_child_removed (GtkContainer    *container,
+                        GtkWidget       *widget,
+                        GtkStackSidebar *sidebar)
+{
+  remove_child (widget, sidebar);
+}
+
+static void
+disconnect_stack_signals (GtkStackSidebar *sidebar)
+{
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
+
+  g_signal_handlers_disconnect_by_func (priv->stack, on_stack_child_added, sidebar);
+  g_signal_handlers_disconnect_by_func (priv->stack, on_stack_child_removed, sidebar);
+  g_signal_handlers_disconnect_by_func (priv->stack, on_child_changed, sidebar);
+  g_signal_handlers_disconnect_by_func (priv->stack, disconnect_stack_signals, sidebar);
+}
+
+static void
+connect_stack_signals (GtkStackSidebar *sidebar)
+{
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
+
+  g_signal_connect_after (priv->stack, "add",
+                          G_CALLBACK (on_stack_child_added), sidebar);
+  g_signal_connect_after (priv->stack, "remove",
+                          G_CALLBACK (on_stack_child_removed), sidebar);
+  g_signal_connect (priv->stack, "notify::visible-child",
+                    G_CALLBACK (on_child_changed), sidebar);
+  g_signal_connect_swapped (priv->stack, "destroy",
+                            G_CALLBACK (disconnect_stack_signals), sidebar);
+}
+
+static void
+gtk_stack_sidebar_dispose (GObject *object)
+{
+  GtkStackSidebar *sidebar = GTK_STACK_SIDEBAR (object);
+
+  gtk_stack_sidebar_set_stack (sidebar, NULL);
+
+  G_OBJECT_CLASS (gtk_stack_sidebar_parent_class)->dispose (object);
+}
+
+static void
+gtk_stack_sidebar_finalize (GObject *object)
+{
+  GtkStackSidebar *sidebar = GTK_STACK_SIDEBAR (object);
+  GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
+
+  g_hash_table_destroy (priv->rows);
+
+  G_OBJECT_CLASS (gtk_stack_sidebar_parent_class)->finalize (object);
+}
+
+static void
+gtk_stack_sidebar_class_init (GtkStackSidebarClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = gtk_stack_sidebar_dispose;
+  object_class->finalize = gtk_stack_sidebar_finalize;
+  object_class->set_property = gtk_stack_sidebar_set_property;
+  object_class->get_property = gtk_stack_sidebar_get_property;
+
+  obj_properties[PROP_STACK] =
+      g_param_spec_object (I_("stack"), P_("Stack"),
+                           P_("Associated stack for this GtkStackSidebar"),
+                           GTK_TYPE_STACK,
+                           G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY);
+
+  g_object_class_install_properties (object_class, N_PROPERTIES, obj_properties);
+}
+
+/**
+ * gtk_stack_sidebar_new:
+ *
+ * Creates a new sidebar.
+ *
+ * Returns: the new #GtkStackSidebar
+ *
+ * Since: 3.16
+ */
+GtkWidget *
+gtk_stack_sidebar_new (void)
+{
+  return GTK_WIDGET (g_object_new (GTK_TYPE_STACK_SIDEBAR, NULL));
+}
+
+/**
+ * gtk_stack_sidebar_set_stack:
+ * @sidebar: a #GtkStackSidebar
+ * @stack: a #GtkStack
+ *
+ * Set the #GtkStack associated with this #GtkStackSidebar.
+ *
+ * The sidebar widget will automatically update according to the order
+ * (packing) and items within the given #GtkStack.
+ *
+ * Since: 3.16
+ */
+void
+gtk_stack_sidebar_set_stack (GtkStackSidebar *sidebar,
+                             GtkStack        *stack)
+{
+  GtkStackSidebarPrivate *priv;
+
+  g_return_if_fail (GTK_IS_SIDEBAR (sidebar));
+  g_return_if_fail (GTK_IS_STACK (stack) || stack == NULL);
+
+  priv = gtk_stack_sidebar_get_instance_private (sidebar);
+
+  if (priv->stack == stack)
+    return;
+
+  if (priv->stack)
+    {
+      disconnect_stack_signals (sidebar);
+      clear_sidebar (sidebar);
+      g_clear_object (&priv->stack);
+    }
+  if (stack)
+    {
+      priv->stack = g_object_ref (stack);
+      populate_sidebar (sidebar);
+      connect_stack_signals (sidebar);
+    }
+
+  gtk_widget_queue_resize (GTK_WIDGET (sidebar));
+
+  g_object_notify (G_OBJECT (sidebar), "stack");
+}
+
+/**
+ * gtk_stack_sidebar_get_stack:
+ * @sidebar: a #GtkStackSidebar
+ *
+ * Retrieves the stack.
+ * See gtk_stack_sidebar_set_stack().
+ *
+ * Returns: (transfer full): the associated #GtkStack or
+ *     %NULL if none has been set explicitly
+ *
+ * Since: 3.16
+ */
+GtkStack *
+gtk_stack_sidebar_get_stack (GtkStackSidebar *sidebar)
+{
+  GtkStackSidebarPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_SIDEBAR (sidebar), NULL);
+
+  priv = gtk_stack_sidebar_get_instance_private (sidebar);
+
+  return GTK_STACK (priv->stack);
+}
diff --git a/gtk/gtkstacksidebar.h b/gtk/gtkstacksidebar.h
new file mode 100644 (file)
index 0000000..70af353
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author:
+ *      Ikey Doherty <michael.i.doherty@intel.com>
+ */
+
+#ifndef __GTK_STACK_SIDEBAR_H__
+#define __GTK_STACK_SIDEBAR_H__
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gtk/gtkbin.h>
+#include <gtk/gtkstack.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_STACK_SIDEBAR           (gtk_stack_sidebar_get_type ())
+#define GTK_STACK_SIDEBAR(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_STACK_SIDEBAR, GtkStackSidebar))
+#define GTK_IS_SIDEBAR(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_STACK_SIDEBAR))
+#define GTK_STACK_SIDEBAR_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_STACK_SIDEBAR, GtkStackSidebarClass))
+#define GTK_IS_SIDEBAR_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_STACK_SIDEBAR))
+#define GTK_STACK_SIDEBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_STACK_SIDEBAR, GtkStackSidebarClass))
+
+typedef struct _GtkStackSidebar        GtkStackSidebar;
+typedef struct _GtkStackSidebarPrivate GtkStackSidebarPrivate;
+typedef struct _GtkStackSidebarClass   GtkStackSidebarClass;
+
+struct _GtkStackSidebar
+{
+  GtkBin parent;
+};
+
+struct _GtkStackSidebarClass
+{
+  GtkBinClass parent_class;
+
+  /* Padding for future expansion */
+  void (*_gtk_reserved1) (void);
+  void (*_gtk_reserved2) (void);
+  void (*_gtk_reserved3) (void);
+  void (*_gtk_reserved4) (void);
+};
+
+GDK_AVAILABLE_IN_3_16
+GType       gtk_stack_sidebar_get_type  (void) G_GNUC_CONST;
+GDK_AVAILABLE_IN_3_16
+GtkWidget * gtk_stack_sidebar_new       (void);
+GDK_AVAILABLE_IN_3_16
+void        gtk_stack_sidebar_set_stack (GtkStackSidebar *sidebar,
+                                         GtkStack        *stack);
+GDK_AVAILABLE_IN_3_16
+GtkStack *  gtk_stack_sidebar_get_stack (GtkStackSidebar *sidebar);
+
+G_END_DECLS
+
+#endif /* __GTK_STACK_SIDEBAR_H__ */
index 6046618ceb0af10371f7fc7a54d437f23466cc70..272959c7275d29240f9110167f7392cd3c26dfd3 100644 (file)
                     <property name="visible">True</property>
                     <property name="orientation">horizontal</property>
                     <child>
-                      <object class="GtkSidebar">
+                      <object class="GtkStackSidebar">
                         <property name="visible">True</property>
                         <property name="stack">object_details</property>
                       </object>
index 3ee1baaaa27474b4c608923215c9a775b9a9e852..78a5244a1345308b215441f2490079e8b1981da2 100644 (file)
@@ -283,7 +283,7 @@ gtk_OBJECTS = \
        gtkseparatortoolitem.obj \
        gtksettings.obj \
        gtkshow.obj \
-       gtksidebar.obj \
+       gtkstacksidebar.obj \
        gtksizegroup.obj \
        gtksizerequest.obj \
        gtkspinbutton.obj \
@@ -476,7 +476,7 @@ gtk_public_h_sources =              \
        gtkseparatortoolitem.h  \
        gtksettings.h           \
        gtkshow.h               \
-       gtksidebar.h            \
+       gtkstacksidebar.h       \
        gtksizegroup.h          \
        gtksizerequest.h        \
        gtksocket.h             \
index a9c8297dccb5e33d66d5e2b91844b0bfd9b68dea..8f58885e2ecf7bffda7ed46de3d9205a2717b4f7 100644 (file)
@@ -230,7 +230,7 @@ gtk/gtkselection.c
 gtk/gtkseparator.c
 gtk/gtkseparatortoolitem.c
 gtk/gtksettings.c
-gtk/gtksidebar.c
+gtk/gtkstacksidebar.c
 gtk/gtksizegroup.c
 gtk/gtksocket.c
 gtk/gtkspinbutton.c
index afa435a07b91cf49deb42b8885d99c7a91b04e90..5c11dbfd4cd20310d152c0c6d222f1b679b1a025 100644 (file)
@@ -231,7 +231,7 @@ gtk/gtkselection.c
 gtk/gtkseparator.c
 gtk/gtkseparatortoolitem.c
 gtk/gtksettings.c
-gtk/gtksidebar.c
+gtk/gtkstacksidebar.c
 gtk/gtksizegroup.c
 gtk/gtksizerequest.c
 gtk/gtksocket.c
index c74c7a2468b2baa520674fcdd350a3d883fd713a..4cf6c07a7729c63e2ab4a39ba8251ed8eea5f0a6 100644 (file)
@@ -137,8 +137,8 @@ main (gint argc,
   gtk_widget_set_halign (stack, GTK_ALIGN_START);
 
   /* Add sidebar before stack */
-  sidebar = gtk_sidebar_new ();
-  gtk_sidebar_set_stack (GTK_SIDEBAR (sidebar), GTK_STACK (stack));
+  sidebar = gtk_stack_sidebar_new ();
+  gtk_stack_sidebar_set_stack (GTK_STACK_SIDEBAR (sidebar), GTK_STACK (stack));
   layout = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
   gtk_box_pack_start (GTK_BOX (layout), sidebar, FALSE, FALSE, 0);
   gtk_box_pack_start (GTK_BOX (layout), stack, TRUE, TRUE, 0);